package edu.udel.mboch.towerdefense;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.Log;
import android.view.HapticFeedbackConstants;
import android.view.MotionEvent;
import android.view.View;

public class MainMenuView extends View implements DialogInterface.OnClickListener
{
	private int width;
	private int height;
	
	private TowerDefenseAndroidActivity activity;
	private TowerDefenseDatabase database;
	private Map<String, Bitmap> images;
	private RectF newGameButton;
	private RectF instructionsButton;
	private RectF exitButton;
	private RectF scoresButton;
	private RectF title;
	private RectF scoresHeader;
	private RectF backButton;
	private RectF clearScoresButton;
	private int mode; //0 = menu, 1 = instructions, 2 = scores
	
	public MainMenuView(TowerDefenseAndroidActivity activity, TowerDefenseDatabase database)
	{
		super(activity);
		this.database = database;
		this.activity = activity;
		mode = 0;
		try
		{
			loadImages();
		}
		catch(IOException e)
		{
			Log.e("TowerDefense", "Failed to load menu images");
		}
	}
	
	protected void onSizeChanged(int w, int h, int oldw, int oldh)
	{
		super.onSizeChanged(w, h, oldw, oldh);
        height = h;
        width = w;
	}
	
	public void setMode(int mode)
	{
		this.mode = mode;
		invalidate();
	}
	
	private void loadImages() throws IOException
	{
		images = new HashMap<String, Bitmap>();
		images.put("NewGameButton", BitmapFactory.decodeStream(getContext().getAssets().open("NewGameButton.png")));
		images.put("ExitButton", BitmapFactory.decodeStream(getContext().getAssets().open("ExitButton.png")));
		images.put("InstructionsButton", BitmapFactory.decodeStream(getContext().getAssets().open("InstructionsButton.png")));
		images.put("ScoresButton", BitmapFactory.decodeStream(getContext().getAssets().open("ScoresButton.png")));
		images.put("Title", BitmapFactory.decodeStream(getContext().getAssets().open("Title.png")));
		images.put("ScoresHeader", BitmapFactory.decodeStream(getContext().getAssets().open("ScoresHeader.png")));
		images.put("BackButton", BitmapFactory.decodeStream(getContext().getAssets().open("BackButton.png")));
		images.put("ClearScoresButton", BitmapFactory.decodeStream(getContext().getAssets().open("ClearScoresButton.png")));
	}
	
	public void onDraw(Canvas canvas)
	{
		Paint paint = new Paint();
		paint.setColor(Color.LTGRAY);
		canvas.drawRect(new Rect(0, 0, width, height), paint);
		if(mode == 0)
		{
			drawMainMenu(canvas);
		}
		else if(mode == 1)
		{
			drawInstructions(canvas);
		}
		else if(mode == 2)
		{
			drawScoreScreen(canvas);
		}
	}
	
	private void drawMainMenu(Canvas canvas)
	{
		Paint paint = new Paint();
		title = new RectF(0, 0, width, 7*height/24);
		newGameButton = new RectF(width/4f, 8*height/24f, 3*width/4f, 11*height/24f);
		instructionsButton = new RectF(width/4f, 12*height/24f, 3*width/4f, 15*height/24f);
		scoresButton = new RectF(width/4f, 16*height/24f, 3*width/4f, 19*height/24f);
		exitButton = new RectF(width/4f, 20*height/24f, 3*width/4f, 23*height/24f);
		Bitmap picture = images.get("Title");
		canvas.drawBitmap(picture, new Rect(0, 0, picture.getWidth(), picture.getHeight()), title, paint);
		picture = images.get("NewGameButton");
		canvas.drawBitmap(picture, new Rect(0, 0, picture.getWidth(), picture.getHeight()), newGameButton, paint);
		picture = images.get("InstructionsButton");
		canvas.drawBitmap(picture,  new Rect(0, 0, picture.getWidth(), picture.getHeight()), instructionsButton, paint);
		picture = images.get("ScoresButton");
		canvas.drawBitmap(picture,  new Rect(0, 0, picture.getWidth(), picture.getHeight()), scoresButton, paint);
		picture = images.get("ExitButton");
		canvas.drawBitmap(picture, new Rect(0, 0, picture.getWidth(), picture.getHeight()), exitButton, paint);
	}
	
	private void drawInstructions(Canvas canvas)
	{
		Paint paint = new Paint();
		title = new RectF(0, 0, width, 7*height/24);
		Bitmap picture = images.get("Title");
		canvas.drawBitmap(picture, new Rect(0, 0, picture.getWidth(), picture.getHeight()), title, paint);
		paint.setColor(Color.RED);
		paint.setTextSize(height/45f);
		String instructions = "The goal of Tower Defense Redux is to prevent monsters from\nreaching the end of a track. Different types of monsters spawn\non one side and work their way towards the end." +
								"If they reach the\nend, you lose a life, and if you run out of lives, you lose! So what\ncan you do to stop the monsters? Build towers of course! You\ncan drag towers onto " +
								"the board near the track to shoot the\nmonsters. The towers will shoot by themselves in different ways.\nBasic Towers shoot only the closest monster to the end. Heavy\nTowers " +
								"shoot all monsters in their range. Slow Towers will slow\nall monsters in their range for a short time. Splash Towers deal a\nportion of their damage to monsters around their target. " +
								"Using\nthe money you get from killing monsters, you can build even\nmore towers. " +
								"If you build a tower and change your mind about it\nlater, you can press the sell button and then tap a tower to sell it\nfor 75% of its cost. So get out there and stop those monsters!";
		Rect bounds = new Rect();
		String[] lines = instructions.split("\n");

	    int yoff = 0;
	    for (int i = 0; i < lines.length; ++i) {
	        canvas.drawText(lines[i], 2, height/3f + yoff, paint);
	        paint.getTextBounds(lines[i], 0, lines[i].length(), bounds);
	        yoff += bounds.height()+10;
	    }
	    backButton = new RectF(width/4f, 20*height/24f, 3*width/4f, 23*height/24f);
	    picture = images.get("BackButton");
		canvas.drawBitmap(picture, new Rect(0, 0, picture.getWidth(), picture.getHeight()), backButton, paint);
	}
	
	private void drawScoreScreen(Canvas canvas)
	{
		Paint paint = new Paint();
		scoresHeader = new RectF(0, 0, width, height/5f);
		Bitmap picture = images.get("ScoresHeader");
		canvas.drawBitmap(picture, new Rect(0, 0, picture.getWidth(), picture.getHeight()), scoresHeader, paint);
		paint.setColor(Color.RED);
		paint.setTextSize(height/40f);
		canvas.drawText("Rank", 0, height/4f, paint);
		canvas.drawText("Player Name", 4*width/36f, height/4f, paint);
		canvas.drawText("Wave", 14*width/36f, height/4f, paint);
		canvas.drawText("Lives", 19*width/36f, height/4f, paint);
		canvas.drawText("Cash", 23*width/36f, height/4f, paint);
		canvas.drawText("Date", 28*width/36f, height/4f, paint);
		ArrayList<TowerDefenseGameRecord> records = (ArrayList<TowerDefenseGameRecord>)database.selectGameRecords();
		for(int i = 0; i<15; i++)
		{
			if(i>=records.size())
				break;
			TowerDefenseGameRecord record = records.get(records.size() - i - 1);
			Date date = new Date(record.getDate());
			String dateString = (date.getMonth()+1) + "-" + date.getDate() + "-" + (date.getYear()+1900);
			canvas.drawText(i + 1 + ".", 0, height/4f + (i+1)*height/30f, paint);
			canvas.drawText(record.getPlayer(), 4*width/36f, height/4f + (i+1)*height/30f, paint);
			canvas.drawText(record.getWave().toString(), 14*width/36f, height/4f + (i+1)*height/30f, paint);
			canvas.drawText(record.getLives().toString(), 19*width/36f, height/4f + (i+1)*height/30f, paint);
			canvas.drawText(record.getCash().toString(), 23*width/36f, height/4f + (i+1)*height/30f, paint);
			canvas.drawText(dateString, 28*width/36f, height/4f + (i+1)*height/30f, paint);
		}
		backButton = new RectF(width/16f, 20*height/24f, 7*width/16f, 23*height/24f);
		picture = images.get("BackButton");
		canvas.drawBitmap(picture, new Rect(0, 0, picture.getWidth(), picture.getHeight()), backButton, paint);
		clearScoresButton = new RectF(9*width/16f, 20*height/24f, 15*width/16f, 23*height/24f);
		picture = images.get("ClearScoresButton");
		canvas.drawBitmap(picture, new Rect(0, 0, picture.getWidth(), picture.getHeight()), clearScoresButton, paint);
	}
	
	public boolean onTouchEvent(MotionEvent event)
	{
		int action = event.getAction();
		if(action == MotionEvent.ACTION_DOWN)
		{
			setHapticFeedbackEnabled(true);
			if(mode == 0)
			{
				if(newGameButton.contains(event.getX(), event.getY()))
				{
					activity.startNewGame();
					performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
				}
				else if(instructionsButton.contains(event.getX(), event.getY()))
				{
					setMode(1);
					performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
				}
				else if(scoresButton.contains(event.getX(), event.getY()))
				{
					setMode(2);
					performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
				}
				else if(exitButton.contains(event.getX(), event.getY()))
				{
					activity.finish();
					performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
				}
			}
			else if(mode == 1)
			{
				if(backButton.contains(event.getX(), event.getY()))
				{
					setMode(0);
					performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
				}
			}
			else if(mode == 2)
			{
				if(backButton.contains(event.getX(), event.getY()))
				{
					setMode(0);
					performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
				}
				else if(clearScoresButton.contains(event.getX(), event.getY()))
				{
					performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
					AlertDialog.Builder alert = new AlertDialog.Builder(getContext());
			    	alert.setTitle("Clear Scores");
			    	alert.setMessage("Are you sure you wish to delete your scores? (This is permanent)");
			    	alert.setPositiveButton("Clear Scores", this);
			    	alert.setNegativeButton("Cancel", this);
			        alert.show();
				}
			}
			setHapticFeedbackEnabled(false);
		}
		return false;
	}

	public void onClick(DialogInterface dialog, int whichButton)
	{
		if(whichButton == -1)
		{
			database.deleteGameRecords();
			invalidate();
		}
		dialog.cancel();
	}
}
